package rad.framework.mda.properties.views;

import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.gmf.runtime.common.ui.services.properties.PropertiesService;
import org.eclipse.jface.util.Assert;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertyConstants;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.eclipse.uml2.common.edit.command.ChangeCommand;
import org.eclipse.uml2.uml.Comment;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.UMLPackage;

/**
 * @author boudyacho
 *
 */
public class DocumentationSection extends AbstractPropertySection {

	private Text nameText;

	private Element umlElement;

	private ModifyListener listener = new ModifyListener() {

		public void modifyText(ModifyEvent arg0) {
			IPropertySource properties = getPropertySource(getComment());
			properties.setPropertyValue(UMLPackage.Literals.COMMENT__BODY,
					nameText.getText());
		}
	};

	/**
	 * @param o
	 * @return
	 */
	protected IPropertySource getPropertySource(Object o) {
		return PropertiesService.getInstance().getPropertySource(o);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#setInput(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
	 */
	public void setInput(IWorkbenchPart part, ISelection selection) {
		super.setInput(part, selection);
		Assert.isTrue(selection instanceof IStructuredSelection);
		Object input = ((IStructuredSelection) selection).getFirstElement();
		Assert.isTrue(input instanceof Element);
		this.umlElement = (Element) input;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#createControls(org.eclipse.swt.widgets.Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
	 */
	public void createControls(Composite parent,TabbedPropertySheetPage aTabbedPropertySheetPage) {
		super.createControls(parent, aTabbedPropertySheetPage);
		Composite composite = getWidgetFactory().createFlatFormComposite(parent);
		FormData data;

		nameText = getWidgetFactory().createText(composite,"", SWT.SCROLL_LINE | SWT.MULTI | SWT.WRAP); 
		data = new FormData();
		data.left = new FormAttachment(0, 0);
		data.right = new FormAttachment(100, 0);
		data.top = new FormAttachment(0, ITabbedPropertyConstants.VSPACE);
		data.height = 2000;
		nameText.setLayoutData(data);
		nameText.addModifyListener(listener);

	}

	/* (non-Javadoc)
	 * @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection#refresh()
	 */
	public void refresh() {
		nameText.removeModifyListener(listener);
		Comment comment = getComment();
		if (comment.getBody() != null) {
			nameText.setText(comment.getBody());
		} else {
			nameText.setText("");
		}
		nameText.addModifyListener(listener);
	}

	/**
	 * @return
	 */
	protected TransactionalEditingDomain getEditingDomain() {
		return TransactionUtil.getEditingDomain(umlElement);
	}

	/**
	 * @return
	 */
	protected Comment getComment() {
		if (!umlElement.getOwnedComments().iterator().hasNext()) {
			getEditingDomain().getCommandStack().execute(
					new ChangeCommand(getEditingDomain(), new Runnable() {
						public void run() {
							umlElement.createOwnedComment();
						}
					}, ""));
		}
		return (Comment) umlElement.getOwnedComments().iterator().next();
	}

}
